#include "TLB.h"
#include "Memory.h"
static TLB tlb;
void TLB_init() {
    for (int i = 0; i < TLB_SIZE; i++) {
        tlb.entries[i].valid = 0;  // 初始化为无效
        tlb.lru_counter[i] = 0;    // 初始 LRU 计数器为 0
    }
}
// TLB.c
void TLB_invalidate_entry(int pid, unsigned VPN) {
    for (int i = 0; i < TLB_SIZE; ++i) {
        if (tlb.entries[i].valid && tlb.entries[i].pid == pid && tlb.entries[i].VPN == VPN) {
            tlb.entries[i].valid = 0;  // 清除 TLB 条目
            return;
        }
    }
}
int TLB_find(int pid, unsigned VPN, PageTableEntry *res, int T) {
    for (int i = 0; i < TLB_SIZE; i++) {
        if (tlb.entries[i].valid && tlb.entries[i].pid == pid && tlb.entries[i].VPN == VPN) {
            tlb.lru_counter[i] = T;  // 更新 LRU 时间戳
            *res = tlb.entries[i].entry;
            return 1;  // 找到
        }
    }
    return 0;  // 未找到
}
void TLB_add(int pid, unsigned VPN, PageTableEntry e, int T) {
    // 查找空闲位置
    for (int i = 0; i < TLB_SIZE; i++) {
        if (!tlb.entries[i].valid) {
       
            tlb.entries[i].valid = 1;
            tlb.entries[i].pid = pid;
            tlb.entries[i].VPN = VPN;
            tlb.entries[i].entry = e;
            tlb.entries[i].dirty = 0;
            tlb.lru_counter[i] = T;
            return;
        }
    }

    // 若无空闲位置，使用 LRU 替换
    int lru_index = 0;
    for (int i = 1; i < TLB_SIZE; i++) {
        if (tlb.lru_counter[i] < tlb.lru_counter[lru_index]) {
            lru_index = i;
        }
    }

    // 获取旧值用于打印
    int old_pid = tlb.entries[lru_index].pid;
    unsigned old_vpn = tlb.entries[lru_index].VPN;

    // 替换最久未使用的表项
    tlb.entries[lru_index].pid = pid;
    tlb.entries[lru_index].VPN = VPN;
    tlb.entries[lru_index].entry = e;
    tlb.entries[lru_index].dirty = 0;
    tlb.lru_counter[lru_index] = T;

    // 打印替换信息（带旧值）
    printf("[%d] TLB entry evicted and replaced: old PID=%d, old VPN=%u → new PID=%d, new VPN=%u\n",
           T, old_pid, old_vpn, pid, VPN);
}
int TLB_setd(int pid, unsigned VPN, int T) {
    for (int i = 0; i < TLB_SIZE; i++) {
        if (tlb.entries[i].valid && tlb.entries[i].pid == pid && tlb.entries[i].VPN == VPN) {
            tlb.entries[i].dirty = 1;  // 设置脏位
            tlb.lru_counter[i] = T;    // 更新 LRU 时间戳
            return 1;  // 成功设置
        }
    }
    return 0;  // 未找到对应表项
}